package net.zoneland.knowledge.utils;

import net.zoneland.knowledge.model.WorkApplyInfoAttachment;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 压缩文件工具类.
 * <p>
 *  提供了一个静态方法zipFile，用于将文件列表压缩成一个zip文件并返回字节数组。还提供了一个私有方法renameFile，用于重命名文件名。
 *  如果文件名中已经包含了上传者的名字，那么就不需要重命名，否则就在文件名中加上上传者的名字和附件ID来重命名文件。
 * </p>
 */
public class FileUtils {

    /**
     * 日志.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);

    private FileUtils() {
        throw new IllegalStateException("FileUtils class");
    }

    /**
     * 压缩文件
     *
     * @param downloadFileDtoList 文件列表
     * @return byte[] 文件字节流
     */
    public static byte[] zipFile(final List<WorkApplyInfoAttachment> downloadFileDtoList) {

        // 将字节写到一个字节输出流里
        final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        try (final ZipOutputStream out = new ZipOutputStream(byteStream)) {
            // 循环文件列表压缩到zip文件中
            for (WorkApplyInfoAttachment downloadFileDto : downloadFileDtoList) {
                // 由于这里的附件名称会出现重名的情况，无法压缩到一个文件中，需要对附件名称加上上传者名字和附件id重新命名
                final String fileName = renameFile(downloadFileDto.getFileName(), downloadFileDto.getUploaderName(), downloadFileDto.getId());
                final ZipEntry entry = new ZipEntry(fileName);
                final byte[] attachmentContent = downloadFileDto.getAttachment();
                entry.setSize(attachmentContent.length);
                out.putNextEntry(entry);
                out.write(attachmentContent);
                out.closeEntry();
            }
        } catch (IOException e) {
            LOGGER.error("压缩zip数据出现异常![{}]", e.getMessage());
        }
        return byteStream.toByteArray();
    }

    /**
     * 重命名文件名
     *
     * @param fileName    文件名
     * @param uploaderName 上传者名字
     * @param id   附件ID
     * @return String 重命名后的文件名
     */
    private static String renameFile(final String fileName, final String uploaderName, final String id) {
        final String[] lst = StringUtils.split(fileName, "\\.");
        final String newFileName = lst[0] + uploaderName + id + "." + lst[1];
        return fileName.contains(uploaderName) ? fileName : newFileName;
    }

}
